package org.study.tk.spring.model;

import com.alibaba.fastjson2.annotation.JSONField;
import jakarta.persistence.*;
import lombok.*;

import java.io.Serializable;
import java.time.LocalDate;
import java.util.Date;

/**
 * Student 实体类：基本数据类型在 Java 类中都有默认值，会导致 MyBatis 在执行相关操作时很难判断当前字段是否为 null，
 * 所以在 MyBatis 环境下使用 Java 实体类时尽量不要使用基本数据类型，都使用对应的包装类型。
 * <p>
 * 常用注解之 @Table
 * 作用：建立实体类和数据库表之间的对应关系。
 * 默认规则：实体类类名首字母小写作为表名。Student 类对应 t_student 表。
 * 用法：在 @Table 注解的 name 属性中指定目标数据库表的表名。
 * <p>
 * 常用注解之 @Id
 * 通用 Mapper 在执行 xxxByPrimaryKey(key)方法时，有两种情况。
 * 情况1：没有使用 @Id 注解明确指定主键字段，通用 Mapper 会将实体类的所有字段一起当做联合主键作为 where 条件。
 * 情况2：使用 @Id 主键明确标记和数据库表中主键字段对应的实体类字段。
 * <p>
 * 常用注解之 @GeneratedValue
 * 作用：让通用 Mapper 在执行 insert 操作之后将数据库自动生成的主键值回写到实体类对象中。
 * 1、自增主键用法(MySQL数据库)：@GeneratedValue(strategy = GenerationType.IDENTITY)
 * 2、序列主键用法(Oracle数据库)：@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "select SEQ_ID.nextval from dual")
 * <p>
 * 常用注解之 @Column
 * 作用：建立实体类字段和数据库表字段之间的对应关系。
 * 默认规则： 实体类字段：驼峰式命名；数据库表字段：使用“_”区分各个单词。
 * 用法：在@Column 注解的 name 属性中指定目标字段的字段名。
 * <p>
 * 常用注解之 @Transient
 * 一般情况下，实体中的字段和数据库表中的字段是一一对应的，但是也有很多情况我们会在实体中增加一些额外的属性，这种情况下，就需要使用 @Transient 注解来告诉通用 Mapper 这不是表中的字段。
 * 默认情况下，只有简单类型(基本类型的包装类)会被自动认为是表中的字段(可以通过配置中的 useSimpleType 控制)。
 *
 * @author Administrator
 * @date 2021-04-20
 */
@Data
@Builder
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "t_student")
public class Student implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private LocalDate birthday;

    private Integer sex;

    private Integer state;

    private String address;

    @Column(name = "class_id")
    private Integer classId;

    @Transient
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
}
